//引用express框架
const express = require('express');
//导入用户集合构造函数
const { User, validateUser } = require('../model/user.js');
//引用bccypt加密模块
const bcrypt = require('bcryptjs');
//创建博客展示页面路由
const admin = express.Router();
//添加Joi验证字符串模块
const Joi = require('joi');
//引入表单二进制转化模块
const formidable = require('formidable');
//引入地址拼接模块
const path = require('path');
//引入文章集合
const { Article } = require('../model/article.js');
//引入分页模块
const pagination = require('mongoose-sex-page');


//渲染登陆页面
admin.get('/login', (req, res) => {
    res.render('admin/login')
});

//实现登录功能
admin.post('/login', async(req, res) => {
    //接受请求参数
    // res.send(req.body);
    const { email, password } = req.body;
    // if (email.trim().length == 0 || password.trim().length == 0) {
    //     return res.status(400).send('<h3>邮件地址或者密码错误</h3>');
    // }
    if (email.trim().length == 0 || password.trim().length == 0) {
        return res.status(400).render('admin/error', { msg: '邮件地址或者密码错误' });
    }
    //根据邮箱地址查询用户信息
    //如果查询到，则是对象，查询不到则为空
    let user = await User.findOne({ email: email });
    //查询到用户
    if (user) {
        //将客户端传递过来的密码和用户信息中的密码比对
        const isValid = await bcrypt.compare(password, user.password)
        if (isValid) {
            //登陆成功
            //将用户名存储在请求对象中
            req.session.username = user.username;
            //将用户角色存储在session中
            req.session.role = user.role;
            // res.send('登陆成功')
            //req内存在app属性，即user.role;开始创建的app
            req.app.locals.userInfo = user;
            //对用户角色进行判断
            if (user.role == 'admin') {
                res.redirect('/admin/user');
            } else {
                res.redirect('/home')
            }


        } else {
            //错误
            res.status(400).render('admin/error', { msg: '邮件地址或者密码错误' });
        }
    } else {
        //没有查询到用户
        res.status(400).render('admin/error', { msg: '邮件地址或者密码错误' });
    }

})

//创建用户列表路由
admin.get('/user', async(req, res) => {
    //标识 表示当前访问的是用户管理页面
    req.app.locals.currentLink = 'user';

    //接收客户端传递过来的当前页参数
    let page = req.query.page || 1;
    //每一页显示的数据条数
    let pagesize = 1;
    //查询用户数据的总数；
    let count = await User.countDocuments();
    //总页数
    let total = Math.ceil(count / pagesize);

    //页码对应的数据查询开始位置
    let start = (page - 1) * pagesize;
    //将用户信息从数据库中查询
    let users = await User.find().limit(pagesize).skip(start);
    // 渲染用户
    res.render('admin/user', {
        users: users,
        page: page,
        total: total
    });
});

//实现退出路由
admin.get('/logout', (req, res) => {
    //删除session cookie
    req.session.destroy(function() {
        res.clearCookie('connect.sid');
        //重定向到登陆页面
        res.redirect('/admin/login');
        //清楚模板中的登录信息
        req.app.locals.userInfo = null;
    });
})

//创建编辑用户页面路由
admin.get('/user-edit', async(req, res) => {
    //标识 表示当前访问的是用户管理页面
    req.app.locals.currentLink = 'user';
    const { message, id } = req.query;
    //如果url有id则认为是修改用户信息操作
    if (id) {
        let user = await User.findOne({ _id: id })
        res.render('admin/user-edit', {
            message: message,
            user: user,
            link: '/admin/user-modify?id=' + id,
            button: '修改'
        });
    } else {
        res.render('admin/user-edit', {
            message: message,
            link: '/admin/user-edit',
            button: '添加'
        });
    }
});

//创建实现添加用户的路由
admin.post('/user-edit', async(req, res, next) => {
    //实施验证
    try {
        await validateUser(req.body)
    } catch (err) {
        //验证没有通过 
        //重定向到用户添加页面
        // return res.redirect(`/admin/user-edit?message=${err.message}`);
        //next只能接受字符串JSON.stringify（）
        return next(JSON.stringify({ path: "/admin/user-edit", message: err.message }))
    }
    //根据用户创建邮箱地址与数据库对比
    let user = await User.findOne({ email: req.body.email });
    // 如果user存在则重定向到注册页面
    if (user) {
        // return res.redirect('/admin/user-edit?message=邮箱地址被占用')
        return next(JSON.stringify({ path: "/admin/user-edit", message: "邮箱地址被占用" }))
    }
    //对密码进行加密
    //生成随机字符串
    const salt = await bcrypt.genSalt(10);
    const password = await bcrypt.hash(req.body.password, salt);
    //替换密码
    req.body.password = password;

    //添加用户到数据库
    await User.create(req.body);
    res.redirect('/admin/user');
});

//创建修改用户信息的路由
admin.post('/user-modify', async(req, res, next) => {
    const { username, email, role, state, password } = req.body;
    const id = req.query.id;
    //用户密码比对，成功后参能修改
    let user = await User.findOne({ _id: id });

    const isValid = await bcrypt.compare(req.body.password, user.password);
    if (isValid) {
        await User.updateOne({ _id: id }, {
            username: username,
            email: email,
            role: role,
            state: state,
        });
        //重定向
        res.redirect('/admin/user');
    } else {
        let obj = { path: "/admin/user-edit", message: "密码错误，修改失败", id: id }
        next(JSON.stringify(obj));
    }
})

//获取删除用户id路由
admin.get('/delete', async(req, res) => {
    // res.send(req.query.id)
    //根据id删除用户
    await User.findOneAndDelete({ _id: req.query.id });
    //重定向
    res.redirect('/admin/user')
})

//文章列表路由
admin.get('/article', async(req, res) => {
    //接收地址的页码
    const page = req.query.page;
    //标识 表示当前访问的是用户管理页面
    req.app.locals.currentLink = 'article';
    //读取数据库  populate多表联合查询
    //page指定当前页
    //size指定煤业显示的数据条数
    //display指定客户端要显示的页码数量
    //exec 向数据库中发送查询请求
    let articles = await pagination(Article).find().page(page).size(2).display(3).populate('author').exec();
    res.send(articles);
    // 渲染页面
    // res.render('admin/article.art');
})

//文章编辑页面路由
admin.get('/article-edit', (req, res) => {
    //标识 表示当前访问的是用户管理页面
    req.app.locals.currentLink = 'article';
    res.render('admin/article-edit')
})

//实现文章添加路由
admin.post('/article-add', (req, res) => {
    //创建表单解析对象
    const form = new formidable.IncomingForm();
    //配置上传地址
    form.uploadDir = path.join(__dirname, '../', 'public', 'uploads');
    //保留上传文件的后缀，默认不保存
    form.keepExtensions = true;
    //解析表单
    form.parse(req, async(err, fields, files) => {
        //err为错误对象，解析失败存储错误星系，正确则为null
        //fields 为对象类型，保存普通表单数据
        //files 为对象类型，保存上传文件的数据
        // res.send(files.cover.path.split('public')[1]);
        //向数据库存储数据
        await Article.create({
            title: fields.title,
            author: fields.author,
            publishDate: fields.publishDate,
            cover: files.cover.path.split('public')[1],
            content: fields.content,
        });
        //重定向
        res.redirect('/admin/article')
    });
    // res.send('ok')

})

//将路由对象作为模块进行导出
module.exports = admin;